package com.mobilesalon.calendar;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

import com.mobilesalon.MobileSalonFactory;
import com.mobilesalon.tools.DateTools;

public class CalendarProviderGoogle implements CalendarProvider {
	private static final String TAG = CalendarProviderGoogle.class.getName();

	private final Context context;

	//
	// Cache Phone Calendars
	//
	List<PhoneCalendarBean> phoneCalendars;

	public CalendarProviderGoogle(Context context) {
		this.context = context;
		final String calendarUriBase = this.getCalendarUriBase();
		ContentResolver contentResolver = context.getContentResolver();

		// Fetch a list of all calendars synced with the device, their display
		// names and whether the user has them selected for display.
		final Cursor cursor = contentResolver.query(Uri.parse(calendarUriBase + "/calendars"),
				null, null, null, null);
		if (cursor == null || !cursor.moveToFirst()) {
			phoneCalendars = Collections.emptyList();
			return;
		}

		final List<PhoneCalendarBean> phoneCalendarBeans = new ArrayList<PhoneCalendarBean>(
				cursor.getCount());

		while (cursor.moveToNext()) {
			final String accountOwner = cursor.getString(cursor.getColumnIndex("ownerAccount"));
			// if (accountOwner.contains("@gmail.com")) {

			final long id = cursor.getLong(cursor.getColumnIndex("_id"));
			final String accountType = cursor
					.getString(cursor.getColumnIndex("_sync_account_type"));
			final String name = cursor.getString(cursor.getColumnIndex("name"));
			final String displayName = cursor.getString(cursor.getColumnIndex("displayName"));
			final String url = cursor.getString(cursor.getColumnIndex("url"));
			final boolean selected = !cursor.getString(cursor.getColumnIndex("selected")).equals(
					"0");

			final PhoneCalendarBean phoneCalendarBean = new PhoneCalendarBean(id, name,
					displayName, accountType, accountOwner, url, selected);

			Log.d(TAG, phoneCalendarBean.toString());
			phoneCalendarBeans.add(phoneCalendarBean);
			// }
		}
		this.phoneCalendars = phoneCalendarBeans;
	}

	public List<PhoneCalendarBean> getPhoneCalendars() {
		return phoneCalendars;
	}

	public List<CalendarEventBean> getCalendarEvents(PhoneCalendarBean phoneCalendar,
			Calendar from, Calendar to) {
		Uri.Builder builder = Uri.parse(this.getCalendarUriBase() + "/instances/when").buildUpon();
		String test = DateTools.TIMESTAMP_DATEFORMAT.format(from.getTime());
		long fromLong = from.getTimeInMillis();
		long toLong = to.getTimeInMillis();

		ContentUris.appendId(builder, fromLong);
		ContentUris.appendId(builder, toLong);

		final ContentResolver contentResolver = MobileSalonFactory.getContext()
				.getContentResolver();
		Cursor eventCursor = contentResolver.query(builder.build(), new String[] { "event_id",
				"title", "begin", "startMinute", "end", "endMinute", "allDay", "contact_data_id",
				"hasAttendeeData", "commentsUri", "description", "eventLocation", "calendar_id",
				"ownerAccount", }, "Calendars.ownerAccount=\"" + phoneCalendar.getAccountOwner() +"\"",
				null, "startDay ASC, startMinute ASC");

		// For a full list of available columns see
		// http://tinyurl.com/yfbg76w

		List<CalendarEventBean> calendarEventBeans = new ArrayList<CalendarEventBean>(
				eventCursor.getCount());

		while (eventCursor.moveToNext()) {

			final long eventId = eventCursor.getLong(eventCursor.getColumnIndex("event_id"));

			final String title = eventCursor.getString(eventCursor.getColumnIndex("title"));

			final Calendar begin = Calendar.getInstance();
			begin.setTime(new Date(eventCursor.getLong(eventCursor.getColumnIndex("begin"))));

			final Calendar end = Calendar.getInstance();
			end.setTime(new Date(eventCursor.getLong(eventCursor.getColumnIndex("end"))));

			final Boolean allDay = !eventCursor.getString(eventCursor.getColumnIndex("allDay"))
					.equals("0");

			final String description = eventCursor.getString(eventCursor
					.getColumnIndex("description"));

			//
			// Attendees
			//
			final List<Attendee> attendees = this.getAttendeesOfEvent(eventId);

			CalendarEventBean calendarEventBean = new CalendarEventBean(phoneCalendar, eventId,
					title, begin, end, allDay, description, attendees);

			Log.d(TAG, calendarEventBean.toString());

			calendarEventBeans.add(calendarEventBean);

		}
		return calendarEventBeans;
	}

	private String getCalendarUriBase() {
		return (android.os.Build.VERSION.SDK_INT >= 8) ? "content://com.android.calendar"
				: "content://calendar";
	}

	/**
	 * Return all attendees of event exept of organizer attendeeRelationship !=
	 * 2
	 * 
	 * @param eventId
	 * @return
	 */
	private List<Attendee> getAttendeesOfEvent(long eventId) {
		Uri.Builder builder = Uri.parse(this.getCalendarUriBase() + "/attendees").buildUpon();

		final ContentResolver contentResolver = MobileSalonFactory.getContext()
				.getContentResolver();

		String[] mapping = { "attendeeName", "attendeePhoneNumber", "_id", "attendeeEmail" };
		Cursor attendeeCursor = contentResolver.query(builder.build(), mapping, "event_id="
				+ eventId + " AND attendeeRelationship != 2", null, null);

		final List<Attendee> attendees = new ArrayList<Attendee>(attendeeCursor.getCount());

		while (attendeeCursor.moveToNext()) {
			String attendeeName = attendeeCursor.getString(attendeeCursor
					.getColumnIndex("attendeeName"));
			String attendeePhoneNumber = attendeeCursor.getString(attendeeCursor
					.getColumnIndex("attendeePhoneNumber"));
			long _id = attendeeCursor.getLong(attendeeCursor.getColumnIndex("_id"));
			String attendeeEmail = attendeeCursor.getString(attendeeCursor
					.getColumnIndex("attendeeEmail"));

			Attendee attendee = new Attendee(_id, attendeeName, attendeePhoneNumber, attendeeEmail);
			attendees.add(attendee);
		}

		attendeeCursor.close();

		return attendees;

	}

	public PhoneCalendarBean getPhoneCalendarsByAccountOwner(String accountOwner) {
		for (PhoneCalendarBean phoneCalendar : phoneCalendars) {
			if (accountOwner.equals(phoneCalendar.getAccountOwner())) {
				return phoneCalendar;
			}
		}
		throw new IllegalStateException("The accountOwner:" + accountOwner
				+ "cannot be found in phone calendar.");
	}

}
